package com.editors;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.RepaintManager;
import javax.swing.TransferHandler;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;

import com.data.DoubleTextField;
import com.data.DrawObject;
import com.data.LineData;
import com.data.Point3D;
import com.data.Polygon3D;
import com.data.PolygonMesh;
import com.data.ZBuffer;
import com.panels.cell.ValuePair;

public class TrackEditor extends Editor implements MouseListener, ActionListener,  ItemListener ,MenuListener,KeyListener,MouseWheelListener,MouseMotionListener,PropertyChangeListener{
	
	int WIDTH=1000;
	int HEIGHT=750;
	int RIGHT_BORDER=200;
	int BOTTOM_BORDER=200;
	
	JPanel center=null;
	JPanel right=null;
	
	Color background_color=Color.BLACK;
	
	Graphics2D graph=null;
	
	PolygonMesh landscape=null;
	
	Vector objects=null;
	
	Vector points=null;
	Vector lines=null;
	
	public Stack oldPoints=new Stack();
	public Stack oldLines=new Stack();
	
	JButton deleteSelection=null;
	private JMenuBar jmb;
	private JMenuItem jmt;
	private JMenuItem jmt2;
	
	JFileChooser fc = new JFileChooser();
	File currentDirectory=null;
	
	int x0=200;
	int y0=200;
	
	double dx=1;
	double dy=1;
	
	int deltax=10;
	int deltay=10;
	private DoubleTextField xcoordinate;
	private DoubleTextField ycoordinate;
	private DoubleTextField zcoordinate;
	private JCheckBox checkMultipleSelection;
	private JButton buildLine;
	private JButton changePoint;
	private JButton deselectAll;
	private JButton selectAll;
	
	public int MAX_STACK_SIZE=10;
	private JMenuItem jmt_undo;
	private DoubleTextField pointsMove;
	private JButton movePointsUp;
	private JButton movePointsDown;
	private JButton movePointsLeft;
	private JButton movePointsRight;
	private JButton movePointsTop;
	private JButton movePointsBottom;
	
	Vector selectedSequence=null;
	private JButton startSequence; 
	
	public Rectangle currentRect=null;
	public boolean isDrawCurrentRect=false;
	private JMenuItem jmt_template;
	private JMenuItem jmt_landscape;
	private BufferedImage[] worldImages;
	private BufferedImage[] objectImages;
	
	private BufferedImage buf=null;
	private JLabel cellTextureLabel;
	private JComboBox chooseCellTexture;
	private JButton chooseCellPanelTexture;
	private JButton change_cell;
	private JButton deselectAllCells;
	private JPanel bottom;
	private DoubleTextField objMove;
	private JButton moveObjUp;
	private JButton moveObjDown;
	private JButton moveObjLeft;
	private JButton moveObjRight;
	private JButton moveObjTop;
	private JButton moveObjBottom;
	private JComboBox chooseObjectTexture;
	private JButton chooseObjectPanelTexture;
	private JCheckBox checkMultiObject;
	private JLabel objectTextureLabel;
	private DoubleTextField objectX;
	private JCheckBox check_objectX;
	private DoubleTextField objectY;
	private JCheckBox check_objectY;
	private DoubleTextField objectZ;
	private JCheckBox check_objectZ;
	private JButton change_object;
	private JButton add_object;
	private JButton delete_object;
	private boolean redrawAfterMenu;
	private JButton deselectAllObjects;
	
	private JLabel screenPoint;
	
	public static void main(String[] args) {
		
		
		TrackEditor te=new TrackEditor();
		
		
		
	}
	
	
	public TrackEditor(){
		

		
	
		
		setTitle("Track editor");
		setSize(WIDTH+RIGHT_BORDER,HEIGHT+BOTTOM_BORDER);
		setLayout(null);
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		buildMenuBar();
		
		center=new JPanel(null);
		center.setBounds(0,0,WIDTH,HEIGHT);
		center.setBackground(background_color);
		center.addMouseListener(this);
		center.addMouseMotionListener(this);
		center.setTransferHandler(new FileTransferhandler());
		center.addMouseWheelListener(this);
		center.addKeyListener(this);
		add(center);		
		
		right=new JPanel(null);
		right.setBounds(WIDTH,0,RIGHT_BORDER,HEIGHT);
		right.addMouseWheelListener(this);
		add(right);
		
		buildRightPanel();
		
		
		bottom=new JPanel(null);
		bottom.setBounds(0,HEIGHT,WIDTH+RIGHT_BORDER,BOTTOM_BORDER);
		bottom.addMouseWheelListener(this);
		add(bottom);
		
		buildBottomPanel();
		
		initialize();
		
		currentDirectory=new File("lib");
		
		RepaintManager.setCurrentManager( 
				new RepaintManager(){

					public void paintDirtyRegions() {


						super.paintDirtyRegions();
						firePropertyChange("paintDirtyRegions",false,true);
						//if(redrawAfterMenu ) {displayAll();redrawAfterMenu=false;}
					}

				}				
		);
			
		
		addPropertyChangeListener(this);
		
		setVisible(true);
	}
	
	



	private void initialize() {
		
		points=new Vector();
		lines=new Vector();
		
		oldPoints=new Stack();
		oldLines=new Stack();
		
		buf=new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
		
		try {
			worldImages=Editor.loadImages();
			
			chooseCellTexture.addItem(new ValuePair("",""));
			
			for(int i=0;i<worldImages.length;i++){

				chooseCellTexture.addItem(new ValuePair(""+i,""+i));

			}

			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
		try {
			objectImages=Editor.loadObjectImages();
			
			
			for(int i=0;i<objectImages.length;i++){

				chooseObjectTexture.addItem(new ValuePair(""+i,""+i));

			}
	
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}


	private void buildMenuBar() {
		
		jmb=new JMenuBar();
		JMenu jm = new JMenu("File");
		jm.addMenuListener(this);
		jmb.add(jm);
		
		jmt=new JMenuItem("Load track");
		jmt.addActionListener(this);
		jm.add(jmt);
		
		jmt2=new JMenuItem("Save track");
		jmt2.addActionListener(this);
		jm.add(jmt2);
		
		
		JMenu jmEdit= new JMenu("Edit");
		jmb.add(jmEdit);
		jmt_template=new JMenuItem("Get template");
		jmt_template.addActionListener(this);
		jmEdit.add(jmt_template);
		
		jmEdit.addSeparator();
		
		jmt_landscape=new JMenuItem("Get landscape");
		jmt_landscape.addActionListener(this);
		jmEdit.add(jmt_landscape);
		
		JMenu jm2 = new JMenu("Do");
		jm2.addMenuListener(this);
		jmb.add(jm2);
		
		jmt_undo=new JMenuItem("Undo");
		jmt_undo.addActionListener(this);
		jmt_undo.setEnabled(false);
		jm2.add(jmt_undo);
		
		
		setJMenuBar(jmb);
		
	}
	
	private void buildBottomPanel() {
		
		int r=10;
		int c=10;

		chooseObjectTexture=new JComboBox();
		chooseObjectTexture.addItem(new ValuePair("",""));
		chooseObjectTexture.addItemListener(this);
		/*chooseTexture.setBounds(35,r,50,20);*/
		chooseObjectTexture.addKeyListener(this);


		chooseObjectPanelTexture=new JButton("Mesh");
		chooseObjectPanelTexture.setBounds(c,r,100,20);
		chooseObjectPanelTexture.addActionListener(this);
		chooseObjectPanelTexture.addKeyListener(this);
		bottom.add(chooseObjectPanelTexture);


		checkMultiObject=new JCheckBox("Multi");
		checkMultiObject.setBounds(c+100,r,80,20);
		checkMultiObject.addKeyListener(this);
		bottom.add(checkMultiObject);

		r+=20;

		objectTextureLabel=new JLabel();
		objectTextureLabel.setFocusable(false);
		objectTextureLabel.setBounds(10,r,100,100);
		Border border=BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
		objectTextureLabel.setBorder(border);
		bottom.add(objectTextureLabel);

		r=10;
		c+=200;

		JLabel jlb=new JLabel("X:");
		jlb.setBounds(c,r,40,20);
		bottom.add(jlb);

		objectX=new DoubleTextField();
		objectX.setBounds(c+40,r,100,20);
		objectX.addActionListener(this);
		objectX.addKeyListener(this);
		bottom.add(objectX);

		check_objectX=new JCheckBox();
		check_objectX.setBounds(c+150,r,20,20);
		check_objectX.addKeyListener(this);
		bottom.add(check_objectX);

		r+=30;

		jlb=new JLabel("Y:");
		jlb.setBounds(c,r,40,20);
		bottom.add(jlb);

		objectY=new DoubleTextField();
		objectY.setBounds(c+40,r,100,20);
		objectY.addActionListener(this);
		objectY.addKeyListener(this);
		bottom.add(objectY);

		check_objectY=new JCheckBox();
		check_objectY.setBounds(c+150,r,20,20);
		check_objectY.addKeyListener(this);
		bottom.add(check_objectY);



		r+=30;

		jlb=new JLabel("Z:");
		jlb.setBounds(c,r,40,20);
		bottom.add(jlb);

		objectZ=new DoubleTextField();
		objectZ.setBounds(c+40,r,100,20);
		objectZ.addActionListener(this);
		objectZ.addKeyListener(this);
		bottom.add(objectZ);

		check_objectZ=new JCheckBox();
		check_objectZ.setBounds(c+150,r,20,20);
		check_objectZ.addKeyListener(this);
		bottom.add(check_objectZ);

		r=10;
		
		c+=200;

		change_object=new JButton("Change object");
		change_object.setBounds(c,r,140,20);
		change_object.addActionListener(this);
		change_object.addKeyListener(this);
		bottom.add(change_object);

		r+=30;

		add_object=new JButton("Add object");
		add_object.setBounds(c,r,140,20);
		add_object.addActionListener(this);
		add_object.addKeyListener(this);
		bottom.add(add_object);

		r+=30;

		delete_object=new JButton("Delete object");
		delete_object.setBounds(c,r,140,20);
		delete_object.addActionListener(this);
		delete_object.addKeyListener(this);
		bottom.add(delete_object);
		
		r+=30;

		deselectAllObjects=new JButton("Deselect all");
		deselectAllObjects.setBounds(c,r,140,20);
		deselectAllObjects.addActionListener(this);
		deselectAllObjects.addKeyListener(this);
		bottom.add(deselectAllObjects);
		
		r=10;
		c+=200;

		bottom.add(buildObjectMovePanel(c,r));
		
		r=10;
		
		c+=150;

		JLabel lscreenpoint = new JLabel();
		lscreenpoint.setText("Position x,y: ");
		lscreenpoint.setBounds(c,r,100,20);
		bottom.add(lscreenpoint);
		screenPoint=new JLabel();
		screenPoint.setText(",");
		screenPoint.setBounds(c+100,r,300,20);
		bottom.add(screenPoint);
	}
	
	private JPanel buildObjectMovePanel(int i, int r) {

		JPanel move=new JPanel();
		move.setBounds(i,r,100,100);
		move.setLayout(null);

		Border border = BorderFactory.createEtchedBorder();
		move.setBorder(border);

		objMove=new DoubleTextField();
		objMove.setBounds(30,40,40,20);
		objMove.setToolTipText("Position increment");
		move.add(objMove);
		objMove.addKeyListener(this);

		moveObjUp=new JButton(new ImageIcon("lib/images/trianglen.jpg"));
		moveObjUp.setBounds(40,10,20,20);
		moveObjUp.addActionListener(this);
		moveObjUp.setFocusable(false);
		move.add(moveObjUp);

		moveObjDown=new JButton(new ImageIcon("lib/images/triangles.jpg"));
		moveObjDown.setBounds(40,70,20,20);
		moveObjDown.addActionListener(this);
		moveObjDown.setFocusable(false);
		move.add(moveObjDown);

		moveObjLeft=new JButton(new ImageIcon("lib/images/triangleo.jpg"));
		moveObjLeft.setBounds(5,40,20,20);
		moveObjLeft.addActionListener(this);
		moveObjLeft.setFocusable(false);
		move.add(moveObjLeft);

		moveObjRight=new JButton(new ImageIcon("lib/images/trianglee.jpg"));
		moveObjRight.setBounds(75,40,20,20);
		moveObjRight.addActionListener(this);
		moveObjRight.setFocusable(false);
		move.add(moveObjRight);

		moveObjTop=new JButton(new ImageIcon("lib/images/up.jpg"));
		moveObjTop.setBounds(5,70,20,20);
		moveObjTop.addActionListener(this);
		moveObjTop.setFocusable(false);
		move.add(moveObjTop);

		moveObjBottom=new JButton(new ImageIcon("lib/images/down.jpg"));
		moveObjBottom.setBounds(75,70,20,20);
		moveObjBottom.addActionListener(this);
		moveObjBottom.setFocusable(false);
		move.add(moveObjBottom);

		return move;

	}


	private void buildRightPanel() {
		
		int r=10;
		
		checkMultipleSelection=new JCheckBox("Multiple selection");
		checkMultipleSelection.setBounds(10,r,150,20);
		checkMultipleSelection.addKeyListener(this);
		right.add(checkMultipleSelection);
		
		r+=30;
		
		JLabel jlb=new JLabel("X:");
		jlb.setBounds(10,r,30,20);
		right.add(jlb);
		
		xcoordinate = new DoubleTextField();
		xcoordinate.setBounds(50,r,100,20);
		xcoordinate.addKeyListener(this);
		right.add(xcoordinate);
		
		r+=30;
		
		jlb=new JLabel("Y:");
		jlb.setBounds(10,r,30,20);
		right.add(jlb);
		
		ycoordinate = new DoubleTextField();
		ycoordinate.setBounds(50,r,100,20);
		ycoordinate.addKeyListener(this);
		right.add(ycoordinate);
		
		r+=30;
		
		jlb=new JLabel("Z:");
		jlb.setBounds(10,r,30,20);
		right.add(jlb);
		
		zcoordinate = new DoubleTextField();
		zcoordinate.setBounds(50,r,100,20);
		zcoordinate.addKeyListener(this);
		right.add(zcoordinate);
		
		r+=30;
		

		startSequence=new JButton("Start sequence");
		startSequence.setBounds(10,r,150,20);
		startSequence.addActionListener(this);
		startSequence.addKeyListener(this);
		right.add(startSequence);
		
		r+=30;
		
		buildLine=new JButton("Build line");
		buildLine.setBounds(10,r,150,20);
		buildLine.addActionListener(this);
		buildLine.addKeyListener(this);
		right.add(buildLine);
		
		r+=30;
		
		changePoint=new JButton("Change point");
		changePoint.setBounds(10,r,150,20);
		changePoint.addActionListener(this);
		changePoint.addKeyListener(this);
		right.add(changePoint);
		
		r+=30;
		
		deselectAll=new JButton("Deselect all");
		deselectAll.setBounds(10,r,150,20);
		deselectAll.addActionListener(this);
		deselectAll.addKeyListener(this);
		right.add(deselectAll);
		
		r+=30;
		
		
		selectAll=new JButton("Select all");
		selectAll.setBounds(10,r,150,20);
		selectAll.addActionListener(this);
		selectAll.addKeyListener(this);
		right.add(selectAll);
		
		r+=30;
		
		deleteSelection=new JButton("Delete selected");
		deleteSelection.setBounds(10,r,150,20);
		deleteSelection.addActionListener(this);
		deleteSelection.addKeyListener(this);
		right.add(deleteSelection);
		
		r+=30;

		right.add(buildPointsMovePanel(30,r));
		
		
		r+=110;
		
		
		right.add(buildTexturePanel(5,r));
	}

	
	private Component buildTexturePanel(int i, int r) {
		
		chooseCellTexture=new JComboBox();
		
		chooseCellTexture.addItemListener(this);
		/*chooseTexture.setBounds(35,r,50,20);*/
		chooseCellTexture.addKeyListener(this);
		
		
		
		JPanel txtPanel=new JPanel();
		txtPanel.setBounds(i,r,150,220);
		txtPanel.setLayout(null);
		txtPanel.setBorder(BorderFactory.createTitledBorder("Texture"));
		
		int rr=20;
		
		chooseCellPanelTexture=new JButton("Texture");
		chooseCellPanelTexture.setBounds(20,rr,100,20);
		chooseCellPanelTexture.addActionListener(this);
		chooseCellPanelTexture.addKeyListener(this);
		txtPanel.add(chooseCellPanelTexture);
		
		rr+=25;
		
		cellTextureLabel=new JLabel();
		cellTextureLabel.setFocusable(false);
		cellTextureLabel.setBounds(20,35,100,100);
		Border border=BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
		cellTextureLabel.setBorder(border);
		txtPanel.add(cellTextureLabel);
		
		rr+=105;
		
		change_cell=new JButton("Change cell");
		change_cell.setBounds(20,rr,100,20);
		change_cell.addActionListener(this);
		change_cell.addKeyListener(this);
		txtPanel.add(change_cell);
		
		rr+=30;
		
		deselectAllCells=new JButton("Deselect all cells");
		deselectAllCells.setBounds(10,rr,130,20);
		deselectAllCells.addActionListener(this);
		deselectAllCells.addKeyListener(this);
		txtPanel.add(deselectAllCells);
		
		
		return txtPanel;
	}


	private JPanel buildPointsMovePanel(int i, int r) {

		JPanel move=new JPanel();
		move.setBounds(i,r,100,100);
		move.setLayout(null);

		Border border = BorderFactory.createEtchedBorder();
		move.setBorder(border);
		
		pointsMove=new DoubleTextField();
		pointsMove.setBounds(30,40,40,20);
		move.add(pointsMove);
		pointsMove.addKeyListener(this);
		
		movePointsUp=new JButton(new ImageIcon("lib/images/trianglen.jpg"));
		movePointsUp.setBounds(40,10,20,20);
		movePointsUp.addActionListener(this);
		movePointsUp.setFocusable(false);
		move.add(movePointsUp);
		
		movePointsDown=new JButton(new ImageIcon("lib/images/triangles.jpg"));
		movePointsDown.setBounds(40,70,20,20);
		movePointsDown.addActionListener(this);
		movePointsDown.setFocusable(false);
		move.add(movePointsDown);
		
		movePointsLeft=new JButton(new ImageIcon("lib/images/triangleo.jpg"));
		movePointsLeft.setBounds(5,40,20,20);
		movePointsLeft.addActionListener(this);
		movePointsLeft.setFocusable(false);
		move.add(movePointsLeft);
		
		movePointsRight=new JButton(new ImageIcon("lib/images/trianglee.jpg"));
		movePointsRight.setBounds(75,40,20,20);
		movePointsRight.addActionListener(this);
		movePointsRight.setFocusable(false);
		move.add(movePointsRight);
		
		movePointsTop=new JButton(new ImageIcon("lib/images/up.jpg"));
		movePointsTop.setBounds(5,70,20,20);
		movePointsTop.addActionListener(this);
		movePointsTop.setFocusable(false);
		move.add(movePointsTop);
		
		movePointsBottom=new JButton(new ImageIcon("lib/images/down.jpg"));
		movePointsBottom.setBounds(75,70,20,20);
		movePointsBottom.addActionListener(this);
		movePointsBottom.setFocusable(false);
		move.add(movePointsBottom);

		return move;

	}

	@Override
	public void paint(Graphics g) {
		super.paint(g);
		draw();
	}


	private void draw() {
		
		
		if(graph==null)
			graph=(Graphics2D) center.getGraphics();
		
		
		Graphics2D bufGraphics=(Graphics2D)buf.getGraphics();

		draw(bufGraphics);

		graph.drawImage(buf,0,0,WIDTH,HEIGHT,null);
		
	}
	
	double calcX(double x,double y){
		
		return x/dx+x0;
	}

	double calcY(double x,double y){
		
		return HEIGHT-(y/dy+y0);
	}
	
	
	double invX(double x,double y){
		
		return dx*(x-x0);
	}

	double invY(double x,double y){
		
		return dy*(-y-y0+HEIGHT);
	}

	private void draw(Graphics2D graph) { 
		
		graph.setColor(background_color);
		graph.fillRect(0,0,WIDTH,HEIGHT);
		
		//landscape
		
		if(landscape!=null){
			
				int sz=landscape.polygonData.size();

				for (int i = 0; i < sz; i++) {
					LineData ld = (LineData) landscape.polygonData.elementAt(i);

					drawPolygon(ld,landscape.points,graph);
				}
			
		}
		
		if(objects!=null){
			
			//here draw objects
			
			for (int i = 0; i < objects.size(); i++) {
				DrawObject dro = (DrawObject) objects.elementAt(i);
				
	
				int xx=(int) calcX(dro.x,dro.y);
				int yy=(int) calcY(dro.x,dro.y);
				
				int w=(int) (objectImages[dro.getIndex()].getWidth()/dx);
				int h=(int) (objectImages[dro.getIndex()].getHeight()/dy);
					
				graph.drawImage(objectImages[dro.getIndex()],xx,yy,w,h,null);
				
				
		        if(dro.isSelected()){
		        	
		        	Color col=new Color(255,0,0,100);
		        	
		        	graph.setColor(col);
		        	graph.fillRect(xx,yy,w,h);
		        	
		        	setObjectPanelData(dro);
		        	
		        }	
				
			}
			
		}
		
		
		graph.setColor(Color.WHITE);
		
		graph.drawLine((int)calcX(0,0),(int)calcY(0,0),(int)calcX(100,0),(int)calcY(100,0));
		graph.drawLine((int)calcX(0,0),(int)calcY(0,0),(int)calcX(0,100),(int)calcY(0,100));
		
		//draw lines
		
		
		
		for (int i = 0; i < lines.size(); i++) {
			
			LineData ld=(LineData) lines.elementAt(i);
			
			Point3D point1 = (Point3D) points.elementAt(ld.getIndex(0));
			Point3D point2 = (Point3D) points.elementAt(ld.getIndex(1));
			
			graph.drawLine((int)calcX(point1.x,point1.y),(int)calcY(point1.x,point1.y),
					(int)calcX(point2.x,point2.y),(int)calcY(point2.x,point2.y)
			);
		}
		
		// draw points
		for (int i = 0; i < points.size(); i++) {
			
			Point3D point = (Point3D) points.elementAt(i);
			
			if(point.isSelected())
				graph.setColor(Color.RED);
			else
				graph.setColor(Color.WHITE);
			
			graph.fillOval((int)calcX(point.x-2,point.y-2),(int)calcY(point.x-2,point.y-2),5,5);
		}
		
		displayCurrentRect(graph);
		
	}




	public void drawPolygon(LineData ld, Point3D[] points, Graphics graph) {
		

		graph.setColor(ZBuffer.fromHexToColor(ld.getHexColor()));
		
        Polygon3D pol = builProjectedPolygon(ld,points);
        
        Rectangle rect=pol.getBounds();
        
        graph.drawImage(worldImages[ld.getTexture_index()],rect.x,
  				rect.y,
  				(int)rect.getWidth(),
  				(int)rect.getHeight(),
  				null
          );
        
        if(ld.isSelected()){
        	
        	Color col=new Color(255,0,0,100);
        	
        	graph.setColor(col);
        	graph.fillPolygon(pol);
        	
        }
        else{
        	
  
        	
        }

		
	}
	
	public Polygon3D builProjectedPolygon(LineData ld, Point3D[] points) {
		
		Polygon3D pol=new Polygon3D();
		
		int size=ld.size();


		for(int i=0;i<size;i++){


			int num=ld.getIndex(i);

			Point3D p=points[num];

			
			int xx=(int) calcX(p.x,p.y);
			int yy=(int) calcY(p.x,p.y);
			
			pol.addPoint(xx,yy);
			

		}
		
		return pol;
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		
		
		int x=e.getX();
		int y=e.getY();
		
		
		
		if(e.getButton()==MouseEvent.BUTTON3){
			
			prepareUndo();
			
			if(points.size()>0){
				
				for (int i = 0; i < points.size(); i++) {
					
					
					Point3D p=(Point3D) points.elementAt(i);
					if(p.isSelected()){
						
						
						p.setSelected(false);
						
						LineData ld=new LineData();
						ld.addIndex(i);
						ld.addIndex(points.size());
						lines.add(ld);
						break;
					}
				}
				
			
				
			}
			
			Point3D point=new Point3D(invX(x,y),invY(x,y),0,true);
			points.add(point);
			
			xcoordinate.setText(point.x);
	    	ycoordinate.setText(point.y);
	    	zcoordinate.setText(point.z);
			
			draw();
			return;
		}
		
		if(!checkMultipleSelection.isSelected())
			deselectAllPoints();
		
		boolean found=false;
        
		for (int i = 0; i < points.size(); i++) {
			
			Point3D point = (Point3D) points.elementAt(i);
			
			Rectangle rect=new Rectangle((int)calcX(point.x-2,point.y-2),(int)calcY(point.x-2,point.y-2),5,5);
			
		    if(rect.contains(x,y)){
		    	point.setSelected(true);
		    	
		    	found=true;
		    	
		    	if(selectedSequence!=null)
		    		selectedSequence.add(i);
		    	
		    	xcoordinate.setText(point.x);
		    	ycoordinate.setText(point.y);
		    	zcoordinate.setText(point.z);
		    	
		        break;
		    }	
				
		}	
		
		if(!found){
			selectPolygon(x,y);
			selectObject(x,y);
		}
		draw();
	}
	
	private void selectObject(int x, int y) {
	
		
		if(objects!=null){
			

			int sz=objects.size();

			for (int i = 0; i < sz; i++) {

				DrawObject dro = (DrawObject) objects.elementAt(i);
				
				
				int xx=(int) calcX(dro.x,dro.y);
				int yy=(int) calcY(dro.x,dro.y);
				
				int w=(int) (objectImages[dro.getIndex()].getWidth()/dx);
				int h=(int) (objectImages[dro.getIndex()].getHeight()/dy);
				
				Rectangle rect=new Rectangle(xx,yy,w,h);
		        
				//System.out.println(x+" "+y+ " "+xx+ " "+yy+ " "+w+ " "+h);
				
		        if(rect.contains(x,y)){
		        	dro.setSelected(true);
		        }	
		        else if(!checkMultiObject.isSelected())
		        	dro.setSelected(false);
		        
			}

		
		}
		
	}


	private void selectPolygon(int x, int y) {
		
		if(landscape!=null){
			

			int sz=landscape.polygonData.size();

			for (int i = 0; i < sz; i++) {
				LineData ld = (LineData) landscape.polygonData.elementAt(i);

		        Polygon3D pol = builProjectedPolygon(ld,landscape.points);
		        
		        Rectangle rect=pol.getBounds();
		        
		        if(rect.contains(x,y)){
		        	ld.setSelected(true);
		        	setCellPanelData(ld);	
		        }	
		        else if(!checkMultipleSelection.isSelected())
		        	ld.setSelected(false);
		        
			}

		
		}
		
	}

	private void setObjectPanelData(DrawObject dro) {
	
		
		chooseObjectTexture.setSelectedIndex(dro.getIndex()+1);
		
		objectX.setText(dro.getX());
		objectY.setText(dro.getY());
		objectZ.setText(dro.getZ());
		
	}
	

	private void cleanObjectPanel() {
		
		chooseObjectTexture.setSelectedIndex(0);
		
		objectX.setText(null);
		objectY.setText(null);
		objectZ.setText(null);
		
	}

	private void setCellPanelData(LineData ld) {


		chooseCellTexture.setSelectedIndex(ld.getTexture_index()+1);
	}


	public void selectPointsWithRectangle() {

		int x0=Math.min(currentRect.x,currentRect.x+currentRect.width);
		int x1=Math.max(currentRect.x,currentRect.x+currentRect.width);
		int y0=Math.min(currentRect.y,currentRect.y+currentRect.height);
		int y1=Math.max(currentRect.y,currentRect.y+currentRect.height);

		for (int i = 0; i < points.size(); i++) {

			Point3D p = (Point3D) points.elementAt(i);


			int x=(int) calcX(p.x,p.y);
			int y=(int) calcY(p.x,p.y);

			if(x>=x0 && x<=x1 && y>=y0 && y<=y1  ){

				p.setSelected(true);

			}

		}

	}

	private void buildLine() {
		
	
		LineData ld=new LineData();
		
		if(selectedSequence==null || selectedSequence.size()<2)
			return;
		
		for (int i = 0; i < selectedSequence.size(); i++) {
			
			
			Integer num= (Integer) selectedSequence.elementAt(i);
	
			ld.addIndex(num.intValue());
			
			
		}
		lines.add(ld);
		selectedSequence=null;
		
		deselectAllPoints();
		draw();
		
	}

	private void deselectAllPoints() {
		
		for (int i = 0; i < points.size(); i++) {
			
			Point3D point = (Point3D) points.elementAt(i);
			
			point.setSelected(false);
		
		}	
		
	}
	

	private void selectAllPoints() {
	
		
		for (int i = 0; i < points.size(); i++) {
			
			Point3D point = (Point3D) points.elementAt(i);
			point.setSelected(true);
		
		}	
		
	}


	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void mousePressed(MouseEvent arg0) {
		
		int xp=arg0.getX();
		int yp=arg0.getY();
		currentRect = new Rectangle(xp, yp, 0, 0);
		
	}
	
	public void displayCurrentRect(Graphics2D bufGraphics) {
		
		if(!isDrawCurrentRect)
			return;
		
		int x0=Math.min(currentRect.x,currentRect.x+currentRect.width);
		int x1=Math.max(currentRect.x,currentRect.x+currentRect.width);
		int y0=Math.min(currentRect.y,currentRect.y+currentRect.height);
		int y1=Math.max(currentRect.y,currentRect.y+currentRect.height);
		
		bufGraphics.setColor(Color.WHITE);
		bufGraphics.drawRect(x0,y0,x1-x0,y1-y0);
		
	}


	@Override
	public void mouseReleased(MouseEvent arg0) {
		updateSize(arg0);
        selectPointsWithRectangle();
        isDrawCurrentRect=false;
        draw();
		
	}

	
	public void prepareUndo() {
		
		jmt_undo.setEnabled(true);
		
		if(oldPoints.size()==MAX_STACK_SIZE){
			
			oldPoints.removeElementAt(0);
			oldLines.removeElementAt(0);
		}
		oldPoints.push(clonePoints(points));
		oldLines.push(cloneLineData(lines));
	}
	
	public void undo() {
		
		if(oldPoints.size()>0)
			points=(Vector) oldPoints.pop();
		if(oldLines.size()>0)
			lines=(Vector) oldLines.pop();
		
		if(oldPoints.size()==0)
			jmt_undo.setEnabled(false);
		
		draw();
		
	}
	
	public Vector clonePoints(Vector oldPoints) {
		
		Vector newPoints=new Vector();
		
		for(int i=0;i<oldPoints.size();i++){
			
			Point3D p=(Point3D) oldPoints.elementAt(i);
			newPoints.add(p.clone());
		}
		
		return newPoints;
	}
	
	public Vector cloneLineData(Vector oldLines) {
		
		Vector newLineData=new Vector();
		
		for(int i=0;i<oldLines.size();i++){

			LineData ld=(LineData) oldLines.elementAt(i);
		
			
			newLineData.add(ld.clone());
		
			
		}
		return newLineData;
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {

		Object obj = arg0.getSource();

		if(obj==deleteSelection)
			deleteSelection();
		else if(obj==jmt)
			loadTrack();
		else if(obj==jmt2)
			saveTrack(); 
		else if(obj==jmt_undo)
			undo();    
		else if(obj==jmt_template)
			getTemplate();    
		else if(obj==jmt_landscape)
			getLandscape();         
		else if(obj==startSequence){
			selectedSequence=new Vector();
			deselectAllPoints();
		}	 
		else if(obj==buildLine)
			buildLine(); 
		else if(obj==changePoint)
			changeSelectedPoint(); 
		else if(obj==deselectAll){
			deselectAllPoints(); 
			draw();
		}
		else if(obj==selectAll){
			selectAllPoints(); 
			draw();
		}
		else if(obj==movePointsBottom){

			moveSelectedPoints(0,0,-1);
			draw();
		}
		else if(obj==movePointsTop){

			moveSelectedPoints(0,0,1);
			draw();
		}
		else if(obj==movePointsLeft){

			moveSelectedPoints(-1,0,0);
			draw();
		}
		else if(obj==movePointsRight){

			moveSelectedPoints(1,0,0);
			draw();
		}
		else if(obj==movePointsUp){

			moveSelectedPoints(0,1,0);
			draw();
		}
		else if(obj==movePointsDown){

			moveSelectedPoints(0,-1,0);
			draw();
		}
		else if(obj==change_cell){
			changeCell();
		}
		else if(obj==chooseCellPanelTexture){

			TexturesPanel tp=new TexturesPanel(worldImages,100,100);

			int indx=tp.getSelectedIndex();
			if(indx!=-1)
				chooseCellTexture.setSelectedIndex(indx+1);

		}
		else if(obj==deselectAllCells){
			deselectAllCells();
		}
		else if(obj==change_object){
			changeObject();
		}
		else if(obj==delete_object){
			deleteObjects();
		}
		else if(obj==add_object){
			addObject();
		}
		else if(obj==chooseObjectPanelTexture){

			TexturesPanel tp=new TexturesPanel(objectImages,100,100);

			int indx=tp.getSelectedIndex();
			if(indx!=-1)
				chooseObjectTexture.setSelectedIndex(indx+1);

		}
		else if(obj==moveObjUp){

			moveSelectedObject(0,1,0);

		}
		else if(obj==moveObjDown){

			moveSelectedObject(0,-1,0);

		}
		else if(obj==moveObjLeft){

			moveSelectedObject(-1,0,0);

		}
		else if(obj==moveObjRight){

			moveSelectedObject(+1,0,0);

		}
		else if(obj==moveObjTop){

			moveSelectedObject(0,0,1);

		}
		else if(obj==moveObjBottom){

			moveSelectedObject(0,0,-1);

		}
		else if(obj==deselectAllObjects){

			deselectAllObjects();

		}
		
		

	}





	public void itemStateChanged(ItemEvent arg0) {

		Object o=arg0.getSource();
		if(o==chooseCellTexture){

			ValuePair val=(ValuePair) chooseCellTexture.getSelectedItem();
			if(!val.getCode().equals("")){

				int num=Integer.parseInt(val.getCode());

				BufferedImage icon=new BufferedImage(100,100,BufferedImage.TYPE_3BYTE_BGR);
				icon.getGraphics().drawImage(worldImages[num],0,0,cellTextureLabel.getWidth(),cellTextureLabel.getHeight(),null);
				ImageIcon ii=new ImageIcon(icon);
				cellTextureLabel.setIcon(ii);


			}
			else
				cellTextureLabel.setIcon(null);

		}
		else if(o==chooseObjectTexture){


			ValuePair val=(ValuePair) chooseObjectTexture.getSelectedItem();
			if(!val.getCode().equals("")){

				int num=Integer.parseInt(val.getCode());

				BufferedImage icon=new BufferedImage(100,100,BufferedImage.TYPE_3BYTE_BGR);
				icon.getGraphics().drawImage(objectImages[num],0,0,objectTextureLabel.getWidth(),objectTextureLabel.getHeight(),null);
				ImageIcon ii=new ImageIcon(icon);
				objectTextureLabel.setIcon(ii);


			}
			else
				objectTextureLabel.setIcon(null);

		}
		
	}


	private void getTemplate() {
		
		
		TrackEditorTemplate tet=new TrackEditorTemplate();
		
		if(tet.getTemplate()!=null ){
			
			PolygonMesh pm=tet.getTemplate();
			
			points=PolygonMesh.fromArrayToVector(pm.points);
					
			lines=pm.polygonData;		
			
		}
		
		draw();
	}
	
	private void getLandscape() {
		
		
		TrackEditorLandscape tet=new TrackEditorLandscape();
		
		if(tet.getLandscape()!=null ){
			
			landscape=tet.getLandscape();
	
		}
		
		draw();
	}


	private void saveTrack() {
		
		fc.setDialogType(JFileChooser.SAVE_DIALOG);
		fc.setDialogTitle("Save Track");
		if(currentDirectory!=null)
			fc.setCurrentDirectory(currentDirectory);
		int returnVal = fc.showOpenDialog(this);
		
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = fc.getSelectedFile();
			saveTrack(file);
			currentDirectory=new File(file.getParent());
		} 
		
	}


	private void saveTrack(File file) {
		
		PrintWriter pw;
		try {
			pw = new PrintWriter(file);
			
			pw.println("<track>");
			
			for (int i = 0; i < points.size(); i++) {
				
				Point3D point = (Point3D) points.elementAt(i);
				
				pw.println("P"+i+":\t"+decomposePoint(point));
				
			}	
			pw.println();
			
			for (int i = 0; i < lines.size(); i++) {
				
				LineData ld = (LineData) lines.elementAt(i);
				
								
				pw.println("L"+i+":\t"+decomposeLineData(ld));
				
			}
			
			//only points edited
			if(lines.size()==0){
				
				int counter=0;
				
				for (int i = 0; i < points.size(); i++) {
					
					
					LineData ld = new LineData();
					ld.addIndex(i);
					ld.addIndex((i+1)%points.size());
					
					pw.println("L"+counter+":\t"+decomposeLineData(ld));
					
					counter++;
					
				}
				
			
				
			}
			pw.println("</track>");
			
			if(landscape!=null){
				
				pw.println("<landscape>");
				saveLines(landscape,pw);
				pw.println("</landscape>");
			}
			
			
			if(objects!=null){
				
				pw.println("<objects>");
				saveObjects(objects,pw);
				pw.println("</objects>");
			}
			
			pw.close();
						
			
		}catch (Exception e) {
			e.printStackTrace();
		}	
	}





	private void loadTrack() {
		
		
		fc.setDialogType(JFileChooser.SAVE_DIALOG);
		fc.setDialogTitle("Load Track");
		if(currentDirectory!=null)
			fc.setCurrentDirectory(currentDirectory);
		
		int returnVal = fc.showOpenDialog(this);
		
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = fc.getSelectedFile();
			loadData(file);
			draw();	
			currentDirectory=new File(file.getParent());
		} 
		
		
		
	}


	private void loadData(File file) {
		
		points=new Vector();
		lines=new Vector();
		
		oldPoints=new Stack();
		oldLines=new Stack();
		
		
		BufferedReader br;
		try {
			br = new BufferedReader(new FileReader(file));
			
			String str=null;
			boolean isTrack=false;
			
			
			while((str=br.readLine())!=null){
				
				if(str.equals("<track>"))
					isTrack=true;
				else if(str.equals("</track>"))
					isTrack=false;
				
				if(isTrack){
				
					if(str.indexOf("P")>=0){
						
						Point3D p=composePoint(str);
						points.add(p);
						
					}
					else if(str.indexOf("L")>=0){	
						
						LineData ld=composeLineData(str);
						lines.add(ld);
					}
				
				}
		
				
			}
			
			br.close();
			
			br = new BufferedReader(new FileReader(file));
			landscape=loadPointsFromFile(br,"landscape");
			
			br = new BufferedReader(new FileReader(file));
			objects=Editor.loadObjectsFromFile(br);
			
		} catch (Exception e) {
		
			e.printStackTrace();
		}
		
	}
	
	
	public static Point3D composePoint(String str) {
		

		
		str=str.substring(1+str.indexOf("\t"));
		
		String[] data=str.split(",");
		
		Point3D p=new Point3D();
		p.x=Double.parseDouble(data[0]);
		p.y=Double.parseDouble(data[1]);
		p.z=Double.parseDouble(data[2]);
		
		return p;
	}
	







	private void deleteSelection() {
		
		prepareUndo();
		
		Hashtable decodePositions=new Hashtable();
		Vector newPoints=new Vector();
		Vector newLines=new Vector();
				
		
		for (int i = 0; i < points.size(); i++) {
			
			Point3D point = (Point3D) points.elementAt(i);
	

			if(point.isSelected()){
				
				
				continue;
			}		
			decodePositions.put(i,newPoints.size());
			newPoints.add(point);
		}
	
		for (int i = 0; i < lines.size(); i++) {
			
			LineData ld=(LineData) lines.elementAt(i);
			boolean valid=true;
			
			for(int j=0;j<ld.size();j++){
				
				Object obj = decodePositions.get(ld.getIndex(j));
				
				
				if(obj==null)
				{	
					
					valid=false;
				    break;
				}
				int newIndex=((Integer)obj).intValue();
				ld.setIndex(j,newIndex);
				
			}
			if(!valid)
				continue;
			
			newLines.add(ld);

		}
		
		points=newPoints;
		lines=newLines;
		
		draw();
		
	}
	

	private void changeSelectedPoint() {
		
		prepareUndo();
		
		for (int i = 0; i < points.size(); i++) {
			
			Point3D point = (Point3D) points.elementAt(i);
	

			if(point.isSelected()){
				
				try{
					if(xcoordinate.getText()!=null && !xcoordinate.getText().equals("") )
						point.setX(xcoordinate.getvalue());
					
					if(ycoordinate.getText()!=null && !ycoordinate.getText().equals("") )
						point.setY(ycoordinate.getvalue());
					
					if(zcoordinate.getText()!=null && !zcoordinate.getText().equals("") )
						point.setZ(zcoordinate.getvalue());
						
				}catch (Exception e) {
					// TODO: handle exception
				}
				continue;
			}		
		
		}
		
		draw();
		
	}
	

	private void deselectAllCells() {
		
		if(landscape==null)
			return;

		for (int i = 0; i <landscape.polygonData.size(); i++) {
			LineData ld = (LineData) landscape.polygonData.elementAt(i);
			ld.setSelected(false);

		}

		draw();
		
	}

	
	
	private void changeCell() {

		if(landscape==null)
			return;

		prepareUndo();
		
		
		for (int i = 0; i <landscape.polygonData.size(); i++) {
			LineData ld = (LineData) landscape.polygonData.elementAt(i);
			if(ld.isSelected()){

				ld.setTexture_index(chooseCellTexture.getSelectedIndex()-1);

			}	

		}

		draw();

	}
	
	private void moveSelectedPoints(int dx, int dy,int dk) {
		
		String sqty=pointsMove.getText();
		
		if(sqty==null || sqty.equals(""))
			return;
		
		double qty=Double.parseDouble(sqty);
		


		prepareUndo();



		for (int i = 0; i < points.size(); i++) {
				
				Point3D point = (Point3D) points.elementAt(i);
		
	
				if(point.isSelected()){
					
					point.x+=qty*dx;
					
					point.y+=qty*dy;
			
					point.z+=qty*dk;
					
				}
		}
	
	}
	

	private void moveSelectedObject(int dx, int dy, int dz) {
		
		if(objects==null)
			return;
		
		prepareUndo();

		String sqty=objMove.getText();

		if(sqty==null || sqty.equals(""))
			return;

		double qty=Double.parseDouble(sqty);

		for(int o=0;o<objects.size();o++){

			DrawObject dro=(DrawObject) objects.elementAt(o);

			if(!dro.isSelected())
				continue;

			dro.setX(dro.getX()+dx*qty);
			dro.setY(dro.getY()+dy*qty);
			dro.setZ(dro.getZ()+dz*qty);
			//dro.setSelected(false);

			dro.buildPolygons();
		}

		draw();
		
	}


	private void addObject() {
		
		if(objects==null)
			objects=new Vector();

		DrawObject dro=new DrawObject();
		dro.setX(0);
		dro.setY(0);
		dro.setZ(0);

		dro.setDx(200);
		dro.setDy(200);
		dro.setDz(200);

		dro.setHexColor("FFFFFF");


		if(!"".equals(objectX.getText())){

			dro.setX(objectX.getvalue());

		}

		if(!"".equals(objectY.getText())){

			dro.setY(objectY.getvalue());

		}

		if(!"".equals(objectZ.getText())){

			dro.setZ(objectZ.getvalue());

		}


		//dro.buildCubicMesh();
		dro.buildPolygons();

		objects.add(dro);

		draw();

	}


	private void deleteObjects() {
		
		if(objects==null)
			return;
		
		Vector filtered=new Vector();

		for (int i = 0; i < objects.size(); i++) {

			DrawObject dro=(DrawObject) objects.elementAt(i);

			if(dro.isSelected()){
				continue;
			}
			filtered.add(dro);
		}	

		objects=filtered;
		
		cleanObjectPanel();

		draw();
		
	}




	private void changeObject() {
	
		if(objects==null)
			return;
		
		prepareUndo();

		for (int i = 0; i < objects.size(); i++) {

			DrawObject dro=(DrawObject) objects.elementAt(i);

			if(dro.isSelected()){



				if(!"".equals(objectX.getText())){

					dro.setX(objectX.getvalue());

				}

				if(!"".equals(objectY.getText())){

					dro.setY(objectY.getvalue());

				}

				if(!"".equals(objectZ.getText())){

					dro.setZ(objectZ.getvalue());

				}


				dro.setIndex(chooseObjectTexture.getSelectedIndex()-1);
				dro.setDimensionFromCubicMesh();
				//dro.buildCubicMesh();
				dro.buildPolygons();

			}
		}	

		draw();
		
	}
	
	private void deselectAllObjects() {
		for (int i = 0; i < objects.size(); i++) {

			DrawObject dro=(DrawObject) objects.elementAt(i);
		    dro.setSelected(false);	
		}	
		draw();
	}

	
	@Override
	public void menuCanceled(MenuEvent arg0) {
		
	}


	@Override
	public void menuDeselected(MenuEvent arg0) {
		redrawAfterMenu=true;
		
	}


	@Override
	public void menuSelected(MenuEvent arg0) {
		redrawAfterMenu=false;
		
	}
	
	public void propertyChange(PropertyChangeEvent arg0) {

		//System.out.println(arg0.getSource().getClass());
		if("paintDirtyRegions".equals(arg0.getPropertyName()) && redrawAfterMenu)
		{
			draw();
			redrawAfterMenu=false;
		}


	}
	
	public class FileTransferhandler extends TransferHandler{
		
		
		public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
			
			for(int i=0;i<transferFlavors.length;i++){
				
				 if (!transferFlavors[i].equals(DataFlavor.javaFileListFlavor))
					 return false;
			}
		    return true;
		}
	
		public boolean importData(JComponent comp, Transferable t) {
		
			try {
				List list=(List) t.getTransferData(DataFlavor.javaFileListFlavor);
				Iterator itera = list.iterator();
				while(itera.hasNext()){
					
					Object o=itera.next();
					if(!(o instanceof File))
						continue;
					File file=(File) o;
					currentDirectory=file.getParentFile();
					loadData(file);
					
					draw();
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
			return false;
		}

		
		
	}
	
	

	@Override
	public void keyPressed(KeyEvent arg0) {
		
		int code=arg0.getKeyCode();
		
		
		if(code==KeyEvent.VK_LEFT)
			translate(+1,0);
		else if(code==KeyEvent.VK_RIGHT)
			translate(-1,0);
		else if(code==KeyEvent.VK_UP)
			translate(0,1);
		else if(code==KeyEvent.VK_DOWN)
			translate(0,-1);
		else if(code==KeyEvent.VK_F1)
			zoom(+1);		
		else if(code==KeyEvent.VK_F2)
			zoom(-1);
	}


	private void zoom(int i) {
		
		
		if(i>0)
			dx=dy=dx/2.0;
		else
			dx=dy=dx*2.0;
		
		draw();
	}


	private void translate(int i, int j) {
		
		
		x0+=i*deltax;
		y0+=j*deltay;
		
		draw();
	}


	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void mouseWheelMoved(MouseWheelEvent arg0) {
		
		
		if(arg0.getUnitsToScroll()<0)
			translate(0,1);
		else
			translate(0,-1);
		
	}
	
	public void mouseDragged(MouseEvent e) {

		isDrawCurrentRect=true;
		updateSize(e);
		
	}
	
    void updateSize(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();
        currentRect.setSize(x - currentRect.x,
                            y - currentRect.y);
       
        
        draw(); 
        
   
    }


	@Override
	public void mouseMoved(MouseEvent e) {
		Point p=e.getPoint();
		screenPoint.setText(invX(p.getX(),p.getY())+","+invY(p.getX(),p.getY()));

	}

}
